package com.syqc.monitor.ui.carsmonitor

import android.os.Handler
import android.os.HandlerThread
import android.os.Looper
import android.os.Message
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import autodispose2.autoDispose
import com.amap.api.maps.AMap
import com.amap.api.maps.model.LatLng
import com.amap.api.maps.model.LatLngBounds
import com.syqc.comlib.AppConfigs
import com.syqc.comlib.UserConstant
import com.syqc.comlib.auto.AutoDisposeViewModel
import com.syqc.comlib.utils.ArrayUtil
import com.syqc.comlib.utils.CacheMMKV
import com.syqc.comlib.utils.GsonUtil
import com.syqc.entity.Driver
import com.syqc.entity.GpsDetail
import com.syqc.entity.Legend
import com.syqc.entity.VideosPass
import com.syqc.maps.clusters.ClusterItem
import com.syqc.maps.utils.MarkerSet
import com.syqc.monitor.R
import com.syqc.net.ServiceHelper
import com.syqc.utils.ToolsUtil
import io.reactivex.rxjava3.core.Flowable
import io.reactivex.rxjava3.disposables.Disposable
import java.util.concurrent.TimeUnit

class MultiVehicleVM : AutoDisposeViewModel() {
    //车队ID
    var teamId = ""

    //是否清除全部车辆
    var isClear = false

    //车辆ID
    var carId = ""

    //是否展示左侧列表
    var isShowAll = false

    //是否刷新聚合
    var isOnlyRefresh = false

    //定位数据
    var gpsDetail: GpsDetail? = null

    //是否显示卡片数据
    private var isShowCard = false

    //是否是单车刷新
    private var isRefresh = false

    //当前车辆下标
    private var index = 0

    //刷新时间
    private var refreshTime = AppConfigs.mapRefresh

    //定时观察者
    private var subscribe: Disposable? = null

    //聚合点集合
    private val clusterItems = arrayListOf<ClusterItem>()

    //车辆位置
    private val _allCars = MutableLiveData<ArrayList<GpsDetail>>()
    val allCars: LiveData<ArrayList<GpsDetail>> get() = _allCars

    //分类数据列表
    private val allTypeGps = ArrayList<ArrayList<GpsDetail>>()

    //卡片分类数据
    private val _gpsTye = MutableLiveData<ArrayList<ArrayList<GpsDetail>>>()
    val gpsType: LiveData<ArrayList<ArrayList<GpsDetail>>> get() = _gpsTye

    //图例
    private val _legends = MutableLiveData<ArrayList<Legend>>()
    val legends: LiveData<ArrayList<Legend>> get() = _legends

    //聚合数据
    private val _clusters = MutableLiveData<ArrayList<ClusterItem>>()
    val clusters: LiveData<ArrayList<ClusterItem>> = _clusters

    //驾驶员数据
    private val _locationLive = MutableLiveData<Boolean>()
    val locationLive: LiveData<Boolean> = _locationLive

    //刷新时间LiveData
    private val _refreshLive = MutableLiveData<Int>()
    val refreshLive: LiveData<Int> = _refreshLive

    //全部定位信息
    private val locations = ArrayList<GpsDetail>()

    //gps处理
    private var gpsHandler: DataHandle? = null
    private val gpsThread = HandlerThread("GpsThread")

    /**
     *  初始化处理线程
     */
    private fun initHandle() {
        gpsThread.start()
        gpsHandler = DataHandle(gpsThread.looper)
    }

    /**
     *  结束处理线程
     */
    private fun stopHandle() {
        gpsHandler?.removeCallbacksAndMessages(null)
        gpsThread.quit()
    }

    /**
     * 开始倒计时刷新
     */
    fun startRefresh() {
        stopRefresh()
        refreshTime = AppConfigs.mapRefresh
        getGpsData()
        _refreshLive.postValue(refreshTime)
        subscribe = Flowable.interval(0, 1, TimeUnit.SECONDS).autoDispose(this).subscribe {
            if (refreshTime == 1) {
                refreshTime = AppConfigs.mapRefresh
                getGpsData()
            } else {
                refreshTime--
            }
            _refreshLive.postValue(refreshTime)
        }
    }

    /**
     * 停止倒计时刷新
     */
    fun stopRefresh() {
        if (subscribe?.isDisposed == false) {
            subscribe?.dispose()
        }
        subscribe = null
    }


    /**
     * 获取定位信息
     */
    private fun getGpsData() {
        getCarsByTeam()
        isOnlyRefresh = false
        if (carId.isNotEmpty()) {
            getCarLocation()
        }
    }

    /**
     * 刷新车辆信息
     *
     */
    fun refreshCar() {
        isRefresh = true
        isOnlyRefresh = true
        getCarLocation()
    }

    /**
     * 获取车辆定位信息
     */
    fun getCarLocation(carId: String) {
        this.carId = carId
        index = getIndexByCarId(carId)
        isOnlyRefresh = true
        getCarLocation()
    }

    /**
     * 获取车辆列表通过车队ID
     */
    private fun getCarsByTeam() {
        if (isTeamEmpty()) return
        ServiceHelper.getRepository().getGpsR(teamId, "", false, filter = false).autoDispose(this)
            .subscribe({
                if (it.isNotEmpty()) {
                    val list = ArrayUtil.sortBy(it, if (isPlate) "carPlate" else "carName", true)
                    locations.clear()
                    locations.addAll(list)
                    sendMessageType(TYPE_CLUSTER)
                    if (isShowAll) _allCars.postValue(locations)
                    if (isShowCard) sendMessageType(TYPE_CLASSIFY)
                } else {
                    typeNum.clear()
                    for (i in 0..5) {
                        typeNum.add(0)
                    }
                    toastLoading(false)
                }
            }, error)
    }

    /**
     *获取车辆定位详情
     */
    private fun getCarLocation() {
        if (isCarEmpty()) return
        ServiceHelper.getRepository().getGpsRInfo("", carId).autoDispose(this).subscribe({
            if (it.isNullOrEmpty()) {
                toast(R.string.toast_no_location_msg)
                gpsDetail = null
                driverInfo.clear()
            } else {
                if (isRefresh) {
                    isRefresh = false
                    toast(R.string.toast_refresh_success)
                }
                gpsDetail = it[0]
                handlePhone(gpsDetail!!)
                _locationLive.postValue(true)
            }
            toastLoading(false)
        }, error)
    }

    /**
     * 获取图例信息
     */
    fun getLegend() {
        if (isCarEmpty()) return
        ServiceHelper.getRepository().getLegend(carId).autoDispose(this).subscribe({
            if (isHasListData(it)) return@subscribe
            if (UserConstant.current_ip == "113.105.152.93") {
                val filter = it.filter { legend -> legend.stateIndex != "6" }
                _legends.postValue(filter as ArrayList<Legend>?)
            } else {
                _legends.postValue(it)
            }
        }, error)
    }


    /**
     * 设置是否展示卡片数据
     *
     * @param isShowCard
     */
    fun isShowCard(isShowCard: Boolean) {
        this.isShowCard = isShowCard
        if (isShowCard) {
            toastLoading(true)
            sendMessageType(TYPE_CLASSIFY)
        }
    }

    //发送处理信息
    private fun sendMessageType(type: Int) {
        val message = Message.obtain()
        message.what = type
        gpsHandler?.sendMessage(message)
    }

    /**
     * 是不是有车辆ID
     */
    private fun isCarEmpty(): Boolean {
        val isEmpty = carId.isEmpty()
        if (isEmpty) toast(R.string.hint_toast_choose_car)
        return isEmpty
    }

    /**
     * 是不是有车队ID
     */
    fun isTeamEmpty(): Boolean {
        val isEmpty = teamId.isEmpty()
        if (isEmpty && isClear) toast(R.string.hint_toast_choose_team)
        return isEmpty && isClear
    }

    fun getBounds(): LatLngBounds? {
        val builder = LatLngBounds.builder()
        synchronized(clusterItems) { // 添加同步锁
            clusterItems.forEach {
                builder.include(it.latLng)
            }
        }
        return try {
            builder.build()
        } catch (e: IllegalStateException) {
            null // 如果没有有效点，返回 null
        }
    }

    /**
     *  根据经纬度获取视图屏幕区域
     */
    fun getBounds(vararg latLng: LatLng): LatLngBounds {
        val builder = LatLngBounds.builder()
        latLng.forEach { builder.include(it) }
        return builder.build()
    }

    /////////////////////////////////处理单车数据//////////////////////////////////////////
    private fun getIndexByCarId(carId: String): Int {
        locations.forEachIndexed { index, gpsSimple ->
            if (carId == gpsSimple.carId) {
                return index
            }
        }
        return 0
    }

    fun nowCar() {
        index = getIndexByCarId(carId)
        isOnlyRefresh = true
        getCarLocation()
    }

    fun previousCar() {
        index -= 1
        if (index < 0) {
            index = 0
            toast(R.string.toast_car_top)
            return
        }
        val carInfo = locations[index]
        if (ToolsUtil.isNoLocation(carInfo.state)) {
            previousCar()
        } else {
            carId = carInfo.carId
        }
        isOnlyRefresh = true
        getCarLocation()
    }

    fun nextCar() {
        index += 1
        if (index >= locations.size) {
            index = locations.size - 1
            toast(R.string.toast_car_bottom)
            return
        }
        val carInfo = locations[index]
        if (ToolsUtil.isNoLocation(carInfo.state)) {
            nextCar()
        } else {
            carId = carInfo.carId
        }
        isOnlyRefresh = true
        getCarLocation()
    }

    /**
     * 获取全部车辆
     *
     */
    fun getAllCars() {
        teamId = ""
        carId = ""
        isClear = false
        stopRefresh()
        startRefresh()
    }

    /**
     * 根据isShowAll 是否展示全部车辆
     */
    fun showAll() {
        if (isShowAll) _allCars.postValue(locations)
    }

    //司机数据
    val driverInfo = mutableListOf<Driver>()
    private fun handlePhone(carInfo: GpsDetail) {
        driverInfo.clear()
        val drvPhone = carInfo.drvPhone
        if (drvPhone.isNotEmpty() && carInfo.drvName.isNotEmpty()) {
            driverInfo.clear()
            val phones = drvPhone.split(",")
            val names = carInfo.drvName.split(",")
            for (i in phones.indices) {
                driverInfo.add(Driver(names[i], phones[i]))
            }
        }
        talkChannel = getAudioChannel(gpsDetail)
    }

    /////////////////////////////////聚合点辅助类//////////////////////////////////////////
    //类型数量
    val typeNum = mutableListOf<Int>()
    private val runCars = ArrayList<GpsDetail>()
    private val stopCars = ArrayList<GpsDetail>()
    private val offlineCars = ArrayList<GpsDetail>()
    private val arrearsCars = ArrayList<GpsDetail>()
    private val alarmCars = ArrayList<GpsDetail>()
    private val locationCars = ArrayList<GpsDetail>()
    private val accCars = ArrayList<GpsDetail>()

    inner class DataHandle(looper: Looper) : Handler(looper) {
        override fun handleMessage(msg: Message) {
            super.handleMessage(msg)
            if (msg.what == TYPE_CLUSTER) {
                val newItems = arrayListOf<ClusterItem>() // 使用临时列表
                val filter = locations.filter { it.glat.isNotEmpty() }
                filter.forEach { item ->
                    val latLng = LatLng(item.glat.toDouble(), item.glng.toDouble())
                    newItems.add(
                        ClusterItem(
                            item.carId,
                            latLng,
                            item.carName,
                            item.carPlate,
                            item.iconLink,
                            item.speed,
                            item.state,
                            item.drct
                        )
                    )
                }
                synchronized(clusterItems) { // 添加同步锁
                    clusterItems.clear()
                    clusterItems.addAll(newItems)
                }
                _clusters.postValue(clusterItems)
                toastLoading(false)
            } else {
                typeNum.clear()
                runCars.clear()
                accCars.clear()
                stopCars.clear()
                offlineCars.clear()
                arrearsCars.clear()
                alarmCars.clear()
                locationCars.clear()
                locations.forEach {
                    when (it.state) {
                        "1", "3" -> offlineCars.add(it)
                        "2" -> {
                            offlineCars.add(it)
                            arrearsCars.add(it)
                        }
                        "4" -> {
                            offlineCars.add(it)
                            alarmCars.add(it)
                        }
                        "6" -> arrearsCars.add(it)
                        "7" -> runCars.add(it)
                        "8" -> {
                            runCars.add(it)
                            alarmCars.add(it)
                        }
                        "9", "10" -> stopCars.add(it)
                        "11", "12" -> {
                            alarmCars.add(it)
                            stopCars.add(it)
                        }
                        "13" -> locationCars.add(it)
                    }
                    if (it.accOn) {
                        accCars.add(it)
                    }
                }
                accCars.sortByDescending { it.curAcc }
                allTypeGps.clear()
                allTypeGps.add(locations)
                allTypeGps.add(offlineCars)
                allTypeGps.add(runCars)
                allTypeGps.add(accCars)
                allTypeGps.add(stopCars)
                allTypeGps.add(alarmCars)
                allTypeGps.add(arrearsCars)
                allTypeGps.add(locationCars)
                typeNum.add(locations.size)
                typeNum.add(offlineCars.size)
                typeNum.add(runCars.size)
                typeNum.add(accCars.size)
                typeNum.add(stopCars.size)
                typeNum.add(alarmCars.size)
                typeNum.add(arrearsCars.size)
                typeNum.add(locationCars.size)
                _gpsTye.postValue(allTypeGps)
                toastLoading(false)
            }
        }
    }

    companion object {
        //处理聚合类
        const val TYPE_CLUSTER = 0

        //处理分类
        const val TYPE_CLASSIFY = 1
    }


    //是否显示车名
    var isPlate: Boolean = MarkerSet.localSet.showPlate


    //是否标准地图
    var mapType = AMap.MAP_TYPE_NORMAL
    fun saveMapType(mapType: Int) {
        this.mapType = mapType
        CacheMMKV.encode("Cars_MapType", mapType)
    }

    //是否显示路况
    var isTraffic = true
    fun saveTraffic() {
        isTraffic = !isTraffic
        CacheMMKV.encode("Cars_isTraffic", isTraffic)
    }

    //是否展示弹窗
    var isShowPopup = false
    fun saveShowPopup(isShowPopup: Boolean) {
        this.isShowPopup = isShowPopup
        CacheMMKV.encode("isShowPopup", isShowPopup)
    }

    //是否聚合
    var isCluster = false
    fun saveCluster(isCluster: Boolean) {
        this.isCluster = isCluster
        CacheMMKV.encode("isCluster", isCluster)
    }

    init {
        isTraffic = CacheMMKV.decodeBoolean("Cars_isTraffic", true)
        isShowPopup = CacheMMKV.decodeBoolean("isShowPopup", true)
        isCluster = CacheMMKV.decodeBoolean("isCluster", true)
        mapType = CacheMMKV.decodeInt("Cars_MapType", AMap.MAP_TYPE_NORMAL)
        initHandle()
    }

    override fun onCleared() {
        super.onCleared()
        stopHandle()
    }

    ///////////////////////////////////////////////////////////////////////////////////////
    //对讲通道号
    var talkChannel = ""

    /**
     * 获取对讲通道号
     *
     * @return
     */
    private fun getAudioChannel(gpsDetail: GpsDetail?): String {
        if (gpsDetail?.videos == null) return ""
        var talkChannel = ""
        gpsDetail.run {
            val entity = GsonUtil.formObject<VideosPass>(videos)
            val channel = entity.tc
            talkChannel = if (channel.isNullOrEmpty()) {
                val passEntitys = entity.vs?.split(",")
                if (passEntitys.isNullOrEmpty()) {
                    ""
                } else {
                    val passInfos = passEntitys[0].split(":")
                    passInfos[0]
                }
            } else {
                channel
            }
        }
        return talkChannel
    }

    fun getMessage() {
//        ServiceHelper.getRepository().getMessage()
//            .autoDispose(this).subscribe({
//                MessageModel.setMessage(it)
//            }, {
//                toast(it.message.toString())
//            })
    }
}